package com.kristou.urgdriver.connection;

import android.app.PendingIntent;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.util.Log;

import java.util.Vector;

import jp.ksksue.driver.serial.FTDriver;

public class SerialConnection implements Connection {
    private FTDriver serialPort;

    private String deviceName;
    private int deviceSpeed = FTDriver.BAUD115200;
    private Vector<Byte> receiveBuffer = new Vector<Byte>();
    public static final String ACTION_USB_PERMISSION = "com.kristou.urgdriver.USB_PERMISSION";


    private String error_message;


    public SerialConnection(UsbManager manager) {
        serialPort = new FTDriver(manager);
        connect();
    }

    public boolean attach(Intent intent) {
        serialPort.usbAttached(intent);
        Log.d("UrgDriver", "USB attached");
        return connect();
    }

    public void detach(Intent intent) {
        serialPort.usbDetached(intent);
        disconnect();
    }

    public void setPermissionIntent(PendingIntent pi) {
        serialPort.setPermissionIntent(pi);
    }

    @Override
    public String what() {
        // TODO Auto-generated method stub
        return error_message;
    }

    @Override
    public boolean connect(String device, int baudrate) {
        deviceName = device;
        deviceSpeed = baudrate;

        return connect();
    }

    @Override
    public boolean connect(String device) {
        deviceName = device;

        return connect();
    }

    @Override
    public boolean disconnect() {
        serialPort.end();
        return true;
    }

    @Override
    public boolean setBaudrate(int baudrate) {
        deviceSpeed = baudrate;
        disconnect();
        return connect();
    }

    @Override
    public int getBaudrate() {
        return deviceSpeed;
    }

    @Override
    public boolean isConnected() {
        return serialPort.isConnected();
    }

    @Override
    public boolean send(String data, int count) {
        int sent = 0;
        if (isConnected()) {
            sent = serialPort.write(data.substring(0, count).getBytes());
        }
        return sent == count;
    }

    @Override
    public String receive(int count, int timeout) {
        String result = "";
        if (isConnected()) {
            long startTime = System.currentTimeMillis();
            byte[] buffer = new byte[1024];
            int len = -1;
            int readBytes = 0;
            while (readBytes <= count) {
                if (receiveBuffer.size() < (count - readBytes)) {
                    len = serialPort.read(buffer);
                    for (int i = 0; i < len; ++i) {
                        receiveBuffer.add(buffer[i]);
                    }
                }

                while (receiveBuffer.size() > 0) {
                    result += (char) receiveBuffer.elementAt(0).byteValue();
                    receiveBuffer.removeElementAt(0);
                    readBytes++;
                    if (readBytes >= count) {
                        return result;
                    }
                }

                long endTime = System.currentTimeMillis();
                int duration = (int) (endTime - startTime);
                if (duration > timeout) {
                    break;
                }
            }
        }
        return result;
    }

    @Override
    public void flush() {
        // TODO Auto-generated method stub

    }

    @Override
    public void clear() {
        receiveBuffer.clear();

    }

    @Override
    public ConnectionType type() {
        return ConnectionType.SERIAL_TYPE;
    }

    @Override
    public void ungetc(char c) {
        receiveBuffer.add(0, (byte) c);

    }

    @Override
    public boolean send(String data) {
        int sent = 0;
        if (isConnected()) {
            sent = serialPort.write(data.getBytes());
        }
        return sent == data.getBytes().length;
    }

    @Override
    public boolean connect() {
        if (serialPort.isConnected()) return true;
        return serialPort.begin(deviceSpeed);
    }

}
